#include "tcpappender.h"
#include <QTimer>
#include <QApplication>
#include <iostream>



TcpAppender::TcpAppender(LogLevel level, QString strRemoteIp, quint16 nRemotePort, QObject *parent)
    : BaseAppender(level, parent),  // 调用基类构造函数（假设BaseAppender继承QObject）
    m_tcpSocket(nullptr),
    m_RemoteIp(strRemoteIp),
    m_RemotePort(nRemotePort),
    m_isConnected(false)
{
    initTcpSocket();  // 初始化TCP socket并连接
    reconnect();// 初始化时发起连接

    // 监听程序退出信号，强制清理
    connect(qApp, &QApplication::aboutToQuit, this, [this]() {
        if (m_tcpSocket) {
            m_tcpSocket->abort();
            m_tcpSocket->deleteLater();
            m_tcpSocket = nullptr;
        }
    });
}

TcpAppender::~TcpAppender()
{
    // 第一步：先解除所有信号槽，避免后续回调干扰
    if (m_tcpSocket) {
        m_tcpSocket->disconnect(this); // 只解除与当前对象的绑定，更安全
    }

    // 第二步：强制关闭socket，不等待（避免阻塞析构）
    QMutexLocker locker(&m_mutex);
    if (m_tcpSocket) {
        m_tcpSocket->abort(); // 立即关闭，不等待数据发送
        m_tcpSocket->deleteLater(); // 延迟销毁，交给事件循环处理
        m_tcpSocket = nullptr;
    }

    m_logCache.clear();
}

void TcpAppender::setRemoteAddr(QString strIp, quint16 nPort)
{
    QMutexLocker locker(&m_mutex);
    m_RemoteIp = strIp;
    m_RemotePort = nPort;
    if (m_isConnected) {
        m_tcpSocket->disconnectFromHost(); // 断开现有连接，触发自动重连
    } else {
        reconnect(); // 未连接时直接发起新连接
    }
}

void TcpAppender::append(LogLevel level, const QString &msg)
{
    if (level < m_level) return;

    QByteArray data = encodeString(msg + "\n");
    QMutexLocker locker(&m_mutex);
    m_logCache.append(data);

    // 3. 若已连接且未在发送中，触发发送
    if (m_isConnected && !m_isSending) {
        sendCache();
    }
}

void TcpAppender::setRetryConfig(int maxRetry, int retryInterval)
{
    QMutexLocker locker(&m_mutex);
    m_maxRetry = maxRetry;
    m_retryInterval = retryInterval;
}

void TcpAppender::setEncoding(QStringConverter::Encoding encoding)
{
    QMutexLocker locker(&m_mutex);
    m_encoding = encoding;
}

void TcpAppender::onConnected()
{
    QMutexLocker locker(&m_mutex);
    m_isConnected = true;
    m_currentRetryCount = 0; // 连接成功重置重试计数
    std::cout<<"TCP connected to" << m_RemoteIp.toStdString() << m_RemotePort<<std::endl;

    // 连接成功后立即发送缓存
    if (!m_logCache.isEmpty() && !m_isSending) {
        sendCache();
    }
}

void TcpAppender::onDisconnected()
{
    QMutexLocker locker(&m_mutex);
    m_isConnected = false;
    m_isSending = false; // 断开连接时重置发送状态
    std::cout << "TCP disconnected from " << m_RemoteIp.toStdString() << " " << m_RemotePort << std::endl;
    // 延迟重连（非阻塞）
    QTimer::singleShot(m_retryInterval, this, &TcpAppender::reconnect);
}

void TcpAppender::onErrorOccurred(QAbstractSocket::SocketError error)
{
    Q_UNUSED(error)
    QMutexLocker locker(&m_mutex);
    m_isConnected = false;
    m_isSending = false;
    std::cerr  << "TCP error: " << m_tcpSocket->errorString().toStdString()<< std::endl;

    // 错误时触发重连
    if (m_currentRetryCount < m_maxRetry) {
        m_currentRetryCount++;
        QTimer::singleShot(m_retryInterval, this, &TcpAppender::reconnect);
    } else {
        std::cerr <<"Reached max retry count, stop retrying";
    }
}


void TcpAppender::onBytesWritten(qint64 bytes)
{
    Q_UNUSED(bytes);
    QMutexLocker locker(&m_mutex);
    // 所有数据发送完成后才重置状态
    if (m_tcpSocket->bytesToWrite() == 0) {
        m_isSending = false;
        // 只有缓存非空时才触发新的发送
        if (!m_logCache.isEmpty()) {
            sendCache();
        }
    }
}





void TcpAppender::retrySendCache()
{
    QMutexLocker locker(&m_mutex);
    if (m_isConnected && !m_logCache.isEmpty() && !m_isSending) {
        sendCache();
    }
}

void TcpAppender::initTcpSocket()
{
    m_tcpSocket = new QTcpSocket(this);
    connect(m_tcpSocket, &QTcpSocket::connected, this, &TcpAppender::onConnected);
    connect(m_tcpSocket, &QTcpSocket::disconnected, this, &TcpAppender::onDisconnected);
    connect(m_tcpSocket, &QTcpSocket::errorOccurred, this, &TcpAppender::onErrorOccurred);
    connect(m_tcpSocket, &QTcpSocket::bytesWritten, this, &TcpAppender::onBytesWritten); // 监听发送完成
}

void TcpAppender::reconnect()
{
    QMutexLocker locker(&m_mutex);
    if (!m_tcpSocket) return;

    // 强制断开现有连接（非阻塞）
    if (m_tcpSocket->state() != QAbstractSocket::UnconnectedState) {
        m_tcpSocket->abort();
    }

    // 非阻塞连接（不等待结果，通过connected信号确认）
    m_tcpSocket->connectToHost(m_RemoteIp, m_RemotePort);
}


void TcpAppender::sendCache()
{
    QMutexLocker locker(&m_mutex); // 加锁确保原子操作

    // 前置条件：未连接/无数据/正在发送，直接返回
    if (!m_isConnected || m_logCache.isEmpty() || m_isSending || !m_tcpSocket) {
        return;
    }

    // 关键：将当前缓存数据转移到临时变量，立即清空原缓存
    QList<QByteArray> tempCache = std::move(m_logCache); // 原子转移，避免后续append干扰
    m_logCache.clear(); // 确保原缓存为空

    m_isSending = true;
    // 合并临时缓存中的数据
    QByteArray allData;
    for (const auto& data : tempCache) {
        allData += data;
    }

    // 发送数据
    qint64 bytesWritten = m_tcpSocket->write(allData);
    m_tcpSocket->flush();

    if (bytesWritten <= 0) {
        std::cerr << "发送失败，数据回退到缓存" << std::endl;
        m_logCache = std::move(tempCache); // 发送失败时将数据回退到缓存
        m_isSending = false;
    }
}


QByteArray TcpAppender::encodeString(const QString &str)
{
    // 根据设置的编码转换字符串为字节数组
    QByteArray logData;

    // Qt6 正确用法：通过 QStringEncoder 进行编码（替代直接构造 QStringConverter）
    QStringEncoder encoder(m_encoding, QStringConverter::Flag::Default);
    if (encoder.isValid()) {
        logData = encoder.encode(str);
    } else {
        logData = str.toLocal8Bit();
    }
    return logData;
}
